package com.pay.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.jboss.netty.util.internal.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.pay.beans.ReturnContent;
import com.pay.beans.WxCustLoginStatusBean;
import com.pay.constants.RedisKeyConstants;
import com.pay.constants.RetConstants;
import com.pay.constants.TemplateTypeConstants;
import com.pay.constants.MposWxRelationConstants;
import com.pay.entity.boss.Customer;
import com.pay.entity.wx.WxCustOperDetail;
import com.pay.entity.wx.WxCustRelation;
import com.pay.enums.SelectSwitch;
import com.pay.enums.UserType;
import com.pay.enums.WxOperType;
import com.pay.enums.YesNo;
import com.pay.mapper.boss.CustomerBossMapper;
import com.pay.mapper.wx.WxCustOperDetailMapper;
import com.pay.mapper.wx.WxCustRelationMapper;
import com.pay.service.WxCustRelationService;
import com.pay.service.WxCustTypeService;
import com.pay.util.RedisUtil;

@Service("wxCustRelationService")
public class WxCustRelationServiceImpl implements WxCustRelationService {

	private Logger logger = LoggerFactory.getLogger(WxCustRelationServiceImpl.class);
	@Resource
	private WxCustRelationMapper wxCustRelationMapper;
	@Resource
	private WxCustOperDetailMapper wxCustOperDetailMapper;
	@Resource
	private WxCustTypeService wxCustTypeService;
	@Resource
	private CustomerBossMapper customerBossMapper;
	
	@Override
	public WxCustRelation findWxCustRelationByCustomerNo(String customerNo) {
		return wxCustRelationMapper.findByCustomerNo(customerNo);
	}

	@Override
	public ReturnContent<Object> updateBindStatusByCustomerNo(String customerNo,String channel) {
		// 验证商户是否绑定
		WxCustRelation wxCustRelation = wxCustRelationMapper.findByCustomerNo(customerNo);
		logger.info("WxCustRelationServiceImpl/updateBindStatusByCustomerNo/customerNo:{},wxCustRelation{}", customerNo,
				JSON.toJSONString(wxCustRelation));
		if (wxCustRelation != null) {
			// 如果已经解绑，直接提示
			if (WxOperType.UNBINDING.name().equals(wxCustRelation.getBindingStatus())) {
				return new ReturnContent<Object>(MposWxRelationConstants.FAIL, "该商户当前已是解绑状态", "");
			}

			String isdefault = wxCustRelation.getIsDefault();
			// 更新当前商户为解绑
			wxCustRelation.setIsDefault(YesNo.N.name());
			wxCustRelation.setBindingStatus(WxOperType.UNBINDING.name());
			wxCustRelationMapper.update(wxCustRelation);

			// 移除openid对应hash
			RedisUtil.hdel(RedisKeyConstants.MULT_ACCOUNT_OPENID_USERNOS + wxCustRelation.getOpenid(), customerNo);
			// 移除userno对应openid
			RedisUtil.removeKeyValue(RedisKeyConstants.MULT_ACCOUNT_USERNO_OPENID + customerNo);

			// 是否是默认--是
			if (YesNo.Y.name().equals(isdefault)) {
				// 移除openid对应默认
				RedisUtil.removeKeyValue(
						RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO + wxCustRelation.getOpenid());
				WxCustRelation wxCustRelation2 = wxCustRelationMapper
						.findLastBindCustByOpenId(wxCustRelation.getOpenid());
				if (wxCustRelation2 != null) {
					wxCustRelation2.setIsDefault(YesNo.Y.name());
					wxCustRelationMapper.update(wxCustRelation2);
					// 重新放置默认商户
					RedisUtil.setKeyValue(
							RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO + wxCustRelation2.getOpenid(),
							wxCustRelation2.getCustomerNo(), 0);
				}
			}
			WxCustOperDetail wxCustOperDetail = new WxCustOperDetail();
			wxCustOperDetail.setOpenid(wxCustRelation.getOpenid());
			wxCustOperDetail.setCreateTime(new Date());
			wxCustOperDetail.setOperType(WxOperType.UNBINDING.name());
			wxCustOperDetail.setUserNo(customerNo);
			wxCustOperDetail.setCustType(wxCustRelation.getCustType());
			wxCustOperDetail.setChannel(channel);// 来源
			wxCustOperDetailMapper.insert(wxCustOperDetail);
//			// 发送“下线”通知
//			String channelTopic="KF";
//			if (!"delete".equals(channel)) {
//				sendExitAccountTemplate(channelTopic, wxCustRelation.getOpenid(), wxCustRelation.getCustomerName());
//			}
			return new ReturnContent<Object>(MposWxRelationConstants.SUCCESS, "解绑成功", "");
		}
		return new ReturnContent<Object>(MposWxRelationConstants.FAIL, "该商户未绑定公众号", "");
	}


	@Override
	public void createMultBindWxUser(String openId, String customerNo, String mcc, String source) throws Exception {
		UserType userType = null;
		if (StringUtils.isBlank(mcc)) {
			userType = wxCustTypeService.getCustTypeByCustomerNo(customerNo);
		} else {
			userType = wxCustTypeService.getCustTypeByMcc(mcc);
		}
		Customer customer=customerBossMapper.findCustomerByCustomerNo(customerNo);
//		Customer customer = customerInterfaceDubbo.findByCustomerNo(customerNo);
		if (customer==null) {
			throw new Exception("商户不存在");
		}
		String customerName=customer.getFullName();
//		String printName=getCustomerPrintName(customerNo);
//		if (StringUtil.notNull(printName)) {
//			customerName=printName;
//		}
//		createActivityTargetQueue(customerNo, customer.getOpenTime());
		//插入数据库
		createBindCust(openId,customerNo,customerName,userType,source);
		logger.info("this loginCheck's openId = " + openId + " , customerNo = " + customerNo);
	}

	@Override
	public ReturnContent<Object> oneKeyBindingCust(String customerNo,
			String openId) {
		return oneKeyBindingCust(customerNo, openId, YesNo.N.name(), "oneKey");
	}
	
	@Override
	public ReturnContent<Object> oneKeyBindingCust(String customerNo,
			String openId, String isDefault, String remarks) {
		List<WxCustRelation> list = wxCustRelationMapper
				.getAllBindCustByOpenId(openId);
		if (list != null && list.size() >= 5) {
			return new ReturnContent<Object>(
					RetConstants.SYSTEM_ERROR, "当前微信已经绑定超过5个商户\n");
		}
		WxCustRelation wxCustRelation = wxCustRelationMapper
				.findByCustomerNo(customerNo);
		if (wxCustRelation != null
				&& "BINDING".equals(wxCustRelation.getBindingStatus())) {
			return new ReturnContent<Object>(RetConstants.ERROR,
					"商编[" + customerNo + "]已被绑定\n");
		}
		Customer customer = customerBossMapper.findCustomerByCustomerNo(customerNo);
		if (customer == null) {
			return new ReturnContent<Object>(RetConstants.ERROR,
					"商编[" + customerNo + "]不存在\n");
		}
		UserType userType = wxCustTypeService
				.getCustTypeByCustomerNo(customerNo);
		if (wxCustRelation == null) {
			createWxCust(openId, customerNo, customer.getFullName(), userType,
					isDefault, remarks, remarks);
		} else {
			updateWxCust(wxCustRelation, openId, isDefault, remarks, remarks);
		}
		return new ReturnContent<Object>(RetConstants.SUCCESS,"");
	}

	private void updateWxCust(WxCustRelation wxCustRelation,String openId, String isDefault, 
			String source,String remark) {
		wxCustRelation.setBindingStatus(WxOperType.BINDING.name());
		Date createTimeDate = new Date();
		wxCustRelation.setIsDefault(isDefault);
		wxCustRelation.setOpenid(openId);
		wxCustRelation.setModifyTime(createTimeDate);
		wxCustRelation.setRemark(remark);
		wxCustRelationMapper.update(wxCustRelation);
		createWxCustHistory(wxCustRelation,source);
		//获得商户参数和设置模版发送状态
		WxCustLoginStatusBean wxCustLoginStatusBean=installWxCustLoginStatusBeanAndSetTemplate(wxCustRelation,SelectSwitch.OFF.name());
		RedisUtil.hset(RedisKeyConstants.MULT_ACCOUNT_OPENID_USERNOS+openId, wxCustRelation.getCustomerNo(), JSON.toJSONString(wxCustLoginStatusBean));
		RedisUtil.setKeyValue(RedisKeyConstants.MULT_ACCOUNT_USERNO_OPENID+wxCustRelation.getCustomerNo(), openId, 0);
		if (YesNo.Y.name().equals(isDefault)) {
			RedisUtil.setKeyValue(RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO + openId, wxCustRelation.getCustomerNo(), 0);
		}
	}

	@Override
	public ReturnContent<Object> addOnkeyBindCustomerToCache(String customerNo,
			String bindCustomerNo) {
		Customer customer=customerBossMapper.findCustomerByCustomerNo(bindCustomerNo);
		if (customer==null) {
			return new ReturnContent<Object>(RetConstants.ERROR,"商编为["+bindCustomerNo+"]的商户不存在");
		}
		WxCustRelation wxCustRelation=wxCustRelationMapper.findByCustomerNo(customerNo);
		if (wxCustRelation==null || "UNBINDING".equals(wxCustRelation.getBindingStatus())) {
			return new ReturnContent<Object>(RetConstants.ERROR,"没有与商编["+customerNo+"]绑定的openId");
		}
		String openId=wxCustRelation.getOpenid();
		RedisUtil.hset(RedisKeyConstants.MULT_ACCOUNT_OPENID_NOOPEN_USERNOS+openId, bindCustomerNo, customer.getFullName());
		
		return new ReturnContent<Object>(RetConstants.SUCCESS,"商编["+bindCustomerNo+"]放入缓存，对应openId["+openId+"]");
	}



	@Override
	public void oneKeyRemoveLogoutCustRedis(String idStart, String idEnd,
			String openId, String customerNo) {
		try {
			if (StringUtils.isNotBlank(openId)&&StringUtils.isNotBlank(customerNo)) {
				removeOpenIdCustRedis(openId,customerNo);
			}else {
				List<WxCustRelation> wxCustRelations=wxCustRelationMapper.findByIdRange(idStart, idEnd,WxOperType.UNBINDING.name());
				for (WxCustRelation wxCustRelation:wxCustRelations) {
					removeOpenIdCustRedis(wxCustRelation.getOpenid(),wxCustRelation.getCustomerNo());
				}
			}
		} catch (Exception e) {
			logger.info("清理解绑商户redis残留数据异常",e);
//			CamelUtil.send("清理解绑商户redis残留数据异常", "liaojinlei", "微信-清理redis残留数据");
		}
	}

	private void removeOpenIdCustRedis(String openId, String customerNo) {
		logger.info("删除残留数据开始openId="+openId+",customerNo="+customerNo);
		String wxcustJson=RedisUtil.hget(RedisKeyConstants.MULT_ACCOUNT_OPENID_USERNOS+openId, customerNo);
		if (StringUtils.isNotBlank(wxcustJson)) {
			RedisUtil.hdel(RedisKeyConstants.MULT_ACCOUNT_OPENID_USERNOS+openId, customerNo);
			logger.info("删除残留数据列表删除完成");
		}
		String wxcustToOpenId=RedisUtil.getValue(RedisKeyConstants.MULT_ACCOUNT_USERNO_OPENID+customerNo);
		if (StringUtils.isNotBlank(wxcustToOpenId)&&wxcustToOpenId.equals(openId)) {
			RedisUtil.removeKeyValue(RedisKeyConstants.MULT_ACCOUNT_USERNO_OPENID+customerNo);
			logger.info("删除残留数据商编对应openId完成");
		}
		String defaultCustomerNo=RedisUtil.getValue(RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO+openId);
		if (defaultCustomerNo.equals(customerNo)) {
			RedisUtil.removeKeyValue(RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO+openId);
			WxCustRelation wxCustRelation2 = wxCustRelationMapper
					.findLastBindCustByOpenId(openId);
			if (wxCustRelation2 != null) {
				wxCustRelation2.setIsDefault(YesNo.Y.name());
				wxCustRelationMapper.update(wxCustRelation2);
				// 重新放置默认商户
				RedisUtil.setKeyValue(
						RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO + wxCustRelation2.getOpenid(),
						wxCustRelation2.getCustomerNo(), 0);
			}
			logger.info("删除残留数据默认商户完成");
		}
	}
	
	private void createBindCust(String openId, String customerNo, String customerName, UserType userType,String source) {
		logger.info("绑定商户开始：openId=" + openId + ",customerNo=" + customerNo + ",customerName=" + customerName
				+ "userType=" + userType+",source"+source);
		WxCustRelation wxCustRelation = wxCustRelationMapper.findByCustomerNo(customerNo);
		
		if (wxCustRelation == null) {
			logger.info("商户初次绑定");
			removeWxCustRelationDefault(openId);
			logger.info("绑定开始");
			createWxCust(openId,customerNo,customerName,userType,YesNo.Y.name(),source,null);
		}else {
			String otherWxCustOpenId=wxCustRelation.getOpenid();
			String otherWxCustIsDefault=wxCustRelation.getIsDefault();
			//更新和创建新的关系
			updateAndAddWxCustRelations(wxCustRelation,openId,customerNo,source);
			if (!openId.equals(otherWxCustOpenId)) {
				//修改原绑定的openId商户信息
				removeOtherWxCustRelations(otherWxCustOpenId,customerNo,otherWxCustIsDefault);
			}
				
		}
	}

	private WxCustRelation createWxCust(String openId, String customerNo, String customerName, UserType userType,
			String isDefault,String source,String remark) {
		WxCustRelation wxCustRelation = new WxCustRelation();
		wxCustRelation.setBindingStatus(WxOperType.BINDING.name());
		Date createTimeDate = new Date();
		wxCustRelation.setCreateTime(createTimeDate);
		wxCustRelation.setCustomerName(customerName);
		wxCustRelation.setCustomerNo(customerNo);
		wxCustRelation.setCustType(userType.name());
		wxCustRelation.setIsDefault(isDefault);
		wxCustRelation.setOpenid(openId);
		wxCustRelation.setModifyTime(createTimeDate);
		wxCustRelation.setRemark(remark);
		wxCustRelationMapper.insert(wxCustRelation);
		createWxCustHistory(wxCustRelation,source);
		//获得商户参数和设置模版发送状态
		WxCustLoginStatusBean wxCustLoginStatusBean=installWxCustLoginStatusBeanAndSetTemplate(wxCustRelation,SelectSwitch.OFF.name());
		RedisUtil.hset(RedisKeyConstants.MULT_ACCOUNT_OPENID_USERNOS+openId, customerNo, JSON.toJSONString(wxCustLoginStatusBean));
		RedisUtil.setKeyValue(RedisKeyConstants.MULT_ACCOUNT_USERNO_OPENID+customerNo, openId, 0);
		if (YesNo.Y.name().equals(isDefault)) {
			RedisUtil.setKeyValue(RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO + openId, customerNo, 0);
		}

		return wxCustRelation;

	}
	

	private WxCustLoginStatusBean installWxCustLoginStatusBeanAndSetTemplate(
			WxCustRelation wxCustRelation,String templatePushStatus) {
		WxCustLoginStatusBean wxCustLoginStatusBean=new WxCustLoginStatusBean();
		wxCustLoginStatusBean.setCustomerName(wxCustRelation.getCustomerName());
		wxCustLoginStatusBean.setCustomerNo(wxCustRelation.getCustomerNo());
		wxCustLoginStatusBean.setIsDefault(wxCustRelation.getIsDefault());
		wxCustLoginStatusBean.setTemplateNo(TemplateTypeConstants.TRADE_ORDER_TEMPLATE);//暂时只有此编号
		wxCustLoginStatusBean.setTradePushSwitch(templatePushStatus);
		wxCustLoginStatusBean.setCustType(wxCustRelation.getCustType());
//TODO		WxCustTemplate wxCustTemplate=wxCustTemplateMapper.findByCustomerNoAndTemplateType(wxCustRelation.getCustomerNo(), TemplateTypeConstants.TRADE_ORDER_TEMPLATE);
//		if (wxCustTemplate!=null) {
//			wxCustTemplate.setStatus(templatePushStatus);
//			wxCustTemplateMapper.update(wxCustTemplate);
//		}else {
//			wxCustTemplate=new WxCustTemplate();
//			wxCustTemplate.setCustomerNo(wxCustRelation.getCustomerNo());
//			wxCustTemplate.setStatus(templatePushStatus);
//			wxCustTemplate.setTemplateType(TemplateTypeConstants.TRADE_ORDER_TEMPLATE);
//			wxCustTemplateMapper.insert(wxCustTemplate);
//		}
		return wxCustLoginStatusBean;
	}

	private void removeWxCustRelationDefault(String openId) {
		WxCustRelation wxCustRelation = wxCustRelationMapper.findIsDefaultByOpenId(openId);
		if (wxCustRelation != null) {
			logger.info("修改默认帐户开始：openId=" + openId + "，原默认商户编号=" + wxCustRelation.getCustomerNo());
			wxCustRelation.setIsDefault(YesNo.N.name());
			wxCustRelationMapper.update(wxCustRelation);
			logger.info("移除openid默认帐号缓存...");
			RedisUtil.removeKeyValue(RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO + openId);
		}
	}

	private void createWxCustHistory(WxCustRelation wxCustRelation,String source) {
		WxCustOperDetail wxCustOperDetail = new WxCustOperDetail();
		wxCustOperDetail.setCreateTime(new Date());
		wxCustOperDetail.setCustType(wxCustRelation.getCustType());
		wxCustOperDetail.setOpenid(wxCustRelation.getOpenid());
		wxCustOperDetail.setOperType(wxCustRelation.getBindingStatus());
		wxCustOperDetail.setUserNo(wxCustRelation.getCustomerNo());
		wxCustOperDetail.setChannel(source);
		wxCustOperDetailMapper.insert(wxCustOperDetail);
	}
	private void updateAndAddWxCustRelations(WxCustRelation wxCustRelation, String openId, String customerNo,String source) {
		//删除缓存中的默认帐户
		removeWxCustRelationDefault(openId);
		// 发送解绑消息
		String otherOpenId = wxCustRelation.getOpenid();
		String otherCustomerName = wxCustRelation.getCustomerName();
		String otherBindingStatus = wxCustRelation.getBindingStatus();
		if (WxOperType.BINDING.name().equals(otherBindingStatus)) {
			try {
				logger.info("发送解绑消息：openId="+otherOpenId);
//				sendExitAccountTemplate("BYOTHER", otherOpenId, otherCustomerName);
			} catch (Exception e) {
				logger.info("发送解绑失败",e);
			}
			wxCustRelation.setBindingStatus(WxOperType.UNBINDING.name());
			createWxCustHistory(wxCustRelation,source);
		}
		
		
		wxCustRelation.setIsDefault(YesNo.Y.name());
		wxCustRelation.setBindingStatus(WxOperType.BINDING.name());
		wxCustRelation.setOpenid(openId);
		wxCustRelation.setModifyTime(new Date());
		wxCustRelationMapper.update(wxCustRelation);
		createWxCustHistory(wxCustRelation,source);
		WxCustLoginStatusBean wxCustLoginStatusBean=installWxCustLoginStatusBeanAndSetTemplate(wxCustRelation, SelectSwitch.OFF.name());
		logger.info("将商户添加到缓存openId="+openId+",customerNo="+customerNo);
		RedisUtil.hset(RedisKeyConstants.MULT_ACCOUNT_OPENID_USERNOS+openId, customerNo, JSON.toJSONString(wxCustLoginStatusBean));
		RedisUtil.setKeyValue(RedisKeyConstants.MULT_ACCOUNT_USERNO_OPENID+customerNo, openId, 0);
		RedisUtil.setKeyValue(RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO+openId, customerNo, 0);
	}
	private void removeOtherWxCustRelations(String otherOpenId, String customerNo, String otherWxCustIsDefault) {
		logger.info("查询原来的openId对应的最后绑定商户，openId="+otherOpenId);
		WxCustRelation wxCustRelation = wxCustRelationMapper.findLastBindCustByOpenId(otherOpenId);
		if (wxCustRelation != null && !customerNo.equals(wxCustRelation.getCustomerNo())) {
			logger.info("删除列表缓存openId=" + otherOpenId + ",customerNo=" + customerNo);
			RedisUtil.hdel(RedisKeyConstants.MULT_ACCOUNT_OPENID_USERNOS + otherOpenId, customerNo);
			logger.info("查询到最新绑定的商户为：" + JSON.toJSONString(wxCustRelation));
			if (YesNo.Y.name().equals(otherWxCustIsDefault)) {
				logger.info("原openId默认帐号替换为：" + wxCustRelation.getCustomerNo());
				wxCustRelation.setIsDefault(YesNo.Y.name());
				wxCustRelationMapper.update(wxCustRelation);
				logger.info("设置openId[" + otherOpenId + "]的默认商户为：" + wxCustRelation.getCustomerNo());
				RedisUtil.setKeyValue(RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO + otherOpenId,
						wxCustRelation.getCustomerNo(), 0);
			}
		} else {
			RedisUtil.hdel(RedisKeyConstants.MULT_ACCOUNT_OPENID_USERNOS + otherOpenId, customerNo);
			logger.info("没有查询到最新绑定的商户，删除默认用户openId：" + otherOpenId);
			RedisUtil.removeKeyValue(RedisKeyConstants.MULT_ACCOUNT_DEFAULT_OPENID_USERNO + otherOpenId);
		}

	}
}
